package com.yunpeng.aidevice.biz.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yunpeng.aidevice.biz.service.IMerchantBizService;
import com.yunpeng.aidevice.common.constant.QueryConstants;
import com.yunpeng.aidevice.common.dto.query.MerchantListQueryDTO;
import com.yunpeng.aidevice.common.dto.save.MerchantSaveDTO;
import com.yunpeng.aidevice.common.enums.DeviceStateEnum;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.aidevice.common.vo.AppUpdateInfoVO;
import com.yunpeng.aidevice.common.vo.SimpleEntityVO;
import com.yunpeng.aidevice.common.vo.merchant.MerchantDetailVO;
import com.yunpeng.aidevice.dao.model.MerchantCountDO;
import com.yunpeng.aidevice.dao.model.entity.MerchantDO;
import com.yunpeng.aidevice.dao.service.*;
import com.yunpeng.common.dto.Result;
import com.yunpeng.common.enums.QueryOperatorEnum;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.common.paging.PagingQueryDTO;
import com.yunpeng.common.paging.query.QueryParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * MerchantBizServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-28
 */
@Service
public class MerchantBizServiceImpl implements IMerchantBizService {

    @Resource
    private IListQueryService listQueryService;

    @Resource
    private IMerchantService merchantService;

    @Resource
    private IDeviceService deviceService;

    @Resource
    private IUserService userService;

    @Resource
    private IDictionariesService dictionariesService;

    @Override
    /**
     * 商户列表
     *
     * @param merchantListQueryDTO
     * @return
     */
    public Result<PagingQueryDTO> queryMerchantList(MerchantListQueryDTO merchantListQueryDTO) {
        PagingQueryDTO pagingQueryDTO = new PagingQueryDTO();
        List<QueryParam> queryParams = new ArrayList<>();
        LinkedHashMap<String, String> orderByMap = new LinkedHashMap<>(16);
        if (merchantListQueryDTO.getInvalidTimeEnd() != null) {
            queryParams.add(QueryParam.quickSetQueryParam("invalid_date",
                    merchantListQueryDTO.getInvalidTimeEnd(), QueryOperatorEnum.LESS_THAT_AND_EQUALS));
        }
        if (merchantListQueryDTO.getCreateTimeStart() != null) {
            queryParams.add(QueryParam.quickSetQueryParam("create_time",
                    merchantListQueryDTO.getCreateTimeStart(), QueryOperatorEnum.GREATER_THAN));
        }
        if (merchantListQueryDTO.getCreateTimeEnd() != null) {
            queryParams.add(QueryParam.quickSetQueryParam("create_time",
                    merchantListQueryDTO.getCreateTimeEnd(), QueryOperatorEnum.LESS_THAT_AND_EQUALS));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getMerchantNumber())) {
            queryParams.add(QueryParam.quickSetQueryParam("number",
                    merchantListQueryDTO.getMerchantNumber(), QueryOperatorEnum.EQUALS));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getMerchantName())) {
            queryParams.add(QueryParam.quickSetQueryParam("name",
                    merchantListQueryDTO.getMerchantName(), QueryOperatorEnum.LEFT_LIKE));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getMerchantUserName())) {
            queryParams.add(QueryParam.quickSetQueryParam("merchant_user",
                    merchantListQueryDTO.getMerchantUserName(), QueryOperatorEnum.LEFT_LIKE));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getMerchantUserPhone())) {
            queryParams.add(QueryParam.quickSetQueryParam("merchant_user_phone",
                    merchantListQueryDTO.getMerchantUserPhone(), QueryOperatorEnum.EQUALS));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getMerchantUserEmail())) {
            queryParams.add(QueryParam.quickSetQueryParam("merchant_user_email",
                    merchantListQueryDTO.getMerchantUserEmail(), QueryOperatorEnum.EQUALS));
        }
        if (StringUtils.isNotBlank(merchantListQueryDTO.getTenantCode())) {
            queryParams.add(QueryParam.quickSetQueryParam("tenant_code",
                    merchantListQueryDTO.getTenantCode(), QueryOperatorEnum.EQUALS));
        }
        queryParams.add(QueryParam.quickSetQueryParam("t", "flag", 1, QueryOperatorEnum.EQUALS));
        orderByMap.put("t.create_time", "desc");
        pagingQueryDTO.setCurrentPage(merchantListQueryDTO.getCurrentPage());
        pagingQueryDTO.setPageSize(merchantListQueryDTO.getPageSize());
        pagingQueryDTO.setConditionList(queryParams);
        pagingQueryDTO.setSortColumnMap(orderByMap);
        PagingQueryDTO resultData = listQueryService.query(pagingQueryDTO, QueryConstants.QUERY_MERCHANT_LIST, null);
        return Result.success(resultData);
    }

    @Override
    /**
     * 商户详情
     *
     * @param merchantCode
     * @param tenantCode
     * @return
     */
    public Result<MerchantDetailVO> merchantDetail(String merchantCode, String tenantCode) {
        MerchantDO merchantDO = merchantService.getByCode(merchantCode, tenantCode);
        if (merchantDO == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "商户不存在");
        }
        MerchantDetailVO merchantDetailVO = new MerchantDetailVO();
        merchantDetailVO.setMerchantCode(merchantDO.getCode());
        merchantDetailVO.setMerchantNumber(merchantDO.getNumber());
        merchantDetailVO.setMerchantName(merchantDO.getName());
        merchantDetailVO.setMerchantAddress(merchantDO.getMerchantAddress());
        merchantDetailVO.setMerchantUserName(merchantDO.getMerchantUser());
        merchantDetailVO.setMerchantUserPhone(merchantDO.getMerchantUserPhone());
        merchantDetailVO.setMerchantUserEmail(merchantDO.getMerchantUserEmail());
        merchantDetailVO.setState(merchantDO.getState());
        merchantDetailVO.setInvalidTime(merchantDO.getInvalidDate());
        if (StringUtils.isNotBlank(merchantDO.getMerchantImages())) {
            merchantDetailVO.setMerchantImages(JSONArray.parseArray(merchantDO.getMerchantImages()));
        }
        return Result.success(merchantDetailVO);
    }

    @Override
    /**
     * 新增商户
     *
     * @param merchantSaveDTO
     * @param operatorCode
     * @return
     */
    public Result<Void> addNewMerchant(MerchantSaveDTO merchantSaveDTO, String operatorCode) {
        if (merchantService.addMerchant(merchantSaveDTO, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 更新商户失效时间
     *
     * @param merchantCode
     * @param tenantCode
     * @param updateTime
     * @param operatorCode
     * @return
     */
    public Result<Void> invalidDateUpdate(String merchantCode, String tenantCode, LocalDateTime updateTime, String operatorCode) {
        if (merchantService.updateInvalidDate(merchantCode, tenantCode, operatorCode, updateTime)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 更新商户信息
     *
     * @param merchantSaveDTO
     * @param operatorCode
     * @return
     */
    public Result<Void> updateMerchant(MerchantSaveDTO merchantSaveDTO, String operatorCode) {
        if (merchantService.modify(merchantSaveDTO, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 获取商户下拉数据
     *
     * @param tenantCod
     * @return
     */
    public Result<List<SimpleEntityVO>> dropDownList(String tenantCod) {
        List<MerchantDO> merchantDOList = merchantService.getByTenant(tenantCod);
        if (merchantDOList == null || merchantDOList.isEmpty()) {
            return Result.success(new ArrayList<>());
        }
        return Result.success(merchantDOList.stream().map(t -> new SimpleEntityVO(t.getCode(), t.getNumber(), t.getName())).collect(Collectors.toList()));
    }

    @Override
    /**
     * 商户固定（用户、设备）统计
     *
     * @param merchantCodes
     * @param tenantCode
     * @return
     */
    public Result<JSONArray> getMerchantCountValue(List<String> merchantCodes, String tenantCode) {
        List<MerchantCountDO> enableDeviceCountList = deviceService.countByMerchant(merchantCodes, tenantCode, DeviceStateEnum.normal.getValue());
        List<MerchantCountDO> allDeviceCountList = deviceService.countByMerchant(merchantCodes, tenantCode, null);
        List<MerchantCountDO> allUserCountList = userService.countByMerchant(merchantCodes, tenantCode, null);
        JSONArray jsonArray = new JSONArray();
        for (String merchantCode : merchantCodes) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("merchantCode", merchantCode);
            for (MerchantCountDO merchantCountDO : enableDeviceCountList) {
                if (merchantCode.equals(merchantCountDO.getMerchantCode())) {
                    jsonObject.put("enableDeviceCount", merchantCountDO.getCount());
                }
            }
            for (MerchantCountDO merchantCountDO : allDeviceCountList) {
                if (merchantCode.equals(merchantCountDO.getMerchantCode())) {
                    jsonObject.put("allDeviceCount", merchantCountDO.getCount());
                }
            }
            for (MerchantCountDO merchantCountDO : allUserCountList) {
                if (merchantCode.equals(merchantCountDO.getMerchantCode())) {
                    jsonObject.put("allUserCount", merchantCountDO.getCount());
                }
            }
            jsonArray.add(jsonObject);
        }
        return Result.success(jsonArray);
    }

    @Override
    /**
     * 禁用启用商户
     *
     * @param disable
     * @param merchantCode
     * @param tenantCode
     * @param operatorCode
     * @return
     */
    public Result<Void> enableDisableMerchant(Boolean disable, String merchantCode, String tenantCode, String operatorCode) {
        if (merchantService.enableDisableMerchant(disable, merchantCode, tenantCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 获取商户设备更新配置
     *
     * @param merchantCode
     * @param tenantCode
     * @return
     */
    public Result<AppUpdateInfoVO> getMerchantAppUpdateInfo(String merchantCode, String tenantCode) {
        return Result.success(merchantService.getAppUpdateInfoVO(merchantCode, tenantCode));
    }

    @Override
    /**
     * 设置app更新时间
     *
     * @param startTime
     * @param endTime
     * @param merchantCode
     * @param tenantCode
     * @param operatorCode
     * @return
     */
    public Result<Void> updateAppUpdateTime(Short startTime, Short endTime, String merchantCode, String tenantCode, String operatorCode) {
        if (merchantService.updateAppUpdateTime(startTime, endTime, merchantCode, tenantCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

}
